home *** CD-ROM | disk | FTP | other *** search
/ Loadstar 145 / 145.d81 / t.disc e < prev    next >
Encoding:
Text File  |  1996-01-01  |  23.3 KB  |  1,033 lines

  1.  
  2.  
  3.  
  4.  
  5.  A complete dissection of Gfx-Zone
  6.  
  7.            by XmikeX
  8.  
  9.  
  10.     [Note from Jeff:] some of this
  11. listing may not print properly in the
  12. 6-column mode.
  13.  
  14.     The following is a disassembly of
  15. the ML code itself.  Although I won't
  16. go through it 100% step by step,
  17. important points shall be perused for
  18. the purposes of clarification, and to
  19. be honest, for a little self-
  20. introspection on my part.
  21.  
  22.   The program starts out quite simply
  23. with the start address and a
  24. labelling of important memory
  25. locations (generally used as pointers
  26. throughout the program).
  27.  
  28.  ;--------------------------------
  29.    *= $c000; start of program
  30.  ;--------------------------------
  31.  point = $fb ; LSB = point  ($fb)
  32.    ; MSB = point+1 ($fc)
  33.  temp  = $cfff ; MSB byte storage
  34.  temp2 = $cffe ; used by FLD routine
  35.  temp3 = $cffd ; $cffa/cffb for
  36.  ; TBB/AMJ player uses these.
  37.  looper = $ccfc ; see pause routine
  38.  hit  = $ccf9 ; see pause routine
  39.  ;----------------------------------
  40.  
  41.  init lda #$36 ; #$36 is our
  42.  ;kill-basic value, so
  43.  sta $01 ; store the kill-basic value
  44. into $01 and move the
  45.   ; basic rom out of the way,
  46. exposing the ram underneath.
  47.  
  48. [AssEd. Note : For general
  49. edification, location $01 works as
  50. follows in C64]
  51. [ - bit 0: ROM/RAM at $a000 1=Basic
  52. 0=RAM]
  53. [ - bit 1: ROM/RAM at $e000 1=Kernal
  54. 0=RAM]
  55. [ - bit 2: ROM or I/O block 1=I/O
  56. 0=ROM]
  57. [ - bits 3,4,5 are cassette
  58. related........]
  59. [ - bits 6 & 7 are not connected in
  60. the C64]
  61. [ - bit 6 checks the status of the
  62. caps lock (ascii/cc) key on C128.]
  63.  
  64.  lda #$00 ; ok...set up accumulator
  65. as #$00
  66.  sta $d020; change screen and
  67.  sta $d021; border to black (i.e.,
  68. #$00)
  69.  sta point; store LSB of pointer
  70. (which is now #$00)
  71.  lda #$00 ; initialize the looper
  72.  sta looper
  73.  
  74.     Ok... So what is going on here?
  75. Basically, we are telling Basic to
  76. take a hike so that we can use the
  77. memory it once inhabited. We are also
  78. setting up the LEAST SIGNIFICANT BYTE
  79. pointer for the indirect Y function.
  80. This is a powerful tool in 6502
  81. assembly and we will get to it later
  82. :). The "looper" is just a memory
  83. location that the program will use in
  84. its "pause" subroutine. Right now, it
  85. is set at zero (#$00).
  86.  
  87.  
  88.    UGLY lda #$fa ; try and tell
  89. tbb/amj music player
  90.  
  91.    sta $105b; what scanline to play
  92. at
  93.  
  94.    amjtune jsr $1000; jsr call to
  95. sys4096/amj's TBB player at $1000
  96.  
  97.  
  98.     This part is really UGLY.
  99. Basically, I tried to extract the
  100. music player and tried to incorporate
  101. it here, but I failed for some
  102. unknown reason. I decided that since
  103. it was proving to be uncooperative
  104. that I should just call it from here
  105. and let it go off on its own. This
  106. presented two problems for me later.
  107. The first was that the music was
  108. playing at raster lines that were
  109. outside the border area. In layman's
  110. terms this means that it would play
  111. in the middle of the screen and a
  112. slight flicker could be seen as the
  113. main code flipped through the pics. I
  114. rectified the situation by finding
  115. out where it was polling its raster
  116. info ($105b) and sticking an #$fa in
  117. there. #$fa is raster line 250, which
  118. should correspond to the lower border
  119. on the screen. Yes, I could have
  120. modified the player code itself, but
  121. I was getting a bit paranoid at this
  122. juncture and decided not to modify
  123. it. The second problem is that by
  124. giving up control to the player
  125. subroutine, I lost control of timing,
  126. an annoyance that which we shall
  127. discuss later. Anyways, as you can
  128. see I call the player in the
  129. 'amjtune' subroutine and let it do
  130. its thing, but even though it is not
  131. in the main code, I've included the
  132. player here for the benefit of the
  133. reader. As this code is from someone
  134. else, I cannot assure a 100% correct
  135. disassembly, but read on..
  136.  
  137.  
  138.     TBB player from SYS4096 tune by
  139. AMJ starts at $1000 and proceeds as
  140. follows: (By the way, TBB is AMJ's
  141. brother...trivia mode over).
  142.  
  143. <start of player code>
  144.  
  145.  > sei ; disables interrupts
  146.  > lda #$01
  147.  > sta $d01a ; set up for scan line
  148.  > lda #$7f
  149.  > sta $dc0d ; enable timer interpts
  150.  > lda #$35  ; lets play with roms
  151.  > sta $01
  152.  > lda #$00
  153.  > ldx #$00
  154.  > ldy #$00
  155.  > jsr $1100 ; jsr to musix init ?
  156.  > lda #$37  ; let's play with roms
  157.  > sta $01
  158.  > lda #<irq ; LSB of irq
  159.  > sta $0314 ; stash it
  160.  > lda #>irq
  161.  > sta $0315 ; MSB of irq
  162.  > lda #$3a
  163.  > sta $d012
  164.  > lda #$1b  ; normalize the screen i
  165. think
  166.  > sta $d011
  167.  > cli ; re-enables interrupts
  168.  > rts ; it used to jmp back to
  169. itself, infinite loop
  170.  > ; as its irq routine played in the
  171. backgroud
  172.  
  173.  >irq lda #$01  ; the irq routine
  174.  > sta $d019
  175.  > lda #$35  ; let's play with roms
  176. again
  177.  > sta $01
  178.  > dec $d020
  179.  > jsr $1103 ; $1103 (!) I think this
  180. jsr's to musix data
  181.  > inc $d020
  182.  > lda #$37  ; let's play with roms
  183. yet again
  184.  > sta $01
  185.  > inc selfmod+1 ; self-modifying
  186. code!!!
  187.  >selfmod lda #$xx  ; #$xx = this is
  188. the byte changed by 'inc selfmod+1'
  189.  > and #$01
  190.  > tax
  191.  > lda #$105b,x ; goes to the scan
  192. line table ?
  193.  > sta $d012 ; sets up the scan line
  194. for irq to occur
  195.  > jmp $ea31 ; go to normal c= irq
  196. return
  197.  
  198. <end of player code>
  199.  
  200.     From $105c to $10a0 or so beyond
  201. this there is some program data of
  202. unknown function.  At around $1100
  203. there is an embedded message by the
  204. authors and then the music data
  205. follows, ending somewhere around
  206. $26b0 if I recall correctly. Please
  207. note that this tune is double-speed
  208. (i.e., plays twice per frame).
  209.  
  210.    <back to main program code>
  211.  
  212.    The initialization steps have
  213. executed and the music player has
  214. been told to start playing.  What is
  215. left now is to present the C/G
  216. pictures to the viewer in a
  217. meaningful way.
  218.  
  219.    The main1 routine that follows
  220. conducts the sequence of the C/G
  221. displays. Its responsibility is to
  222. load and store the MOST SIGNIFICANT
  223. BYTE of the address (location) of
  224. each starting pic for a given pattern
  225. of displays and then branch out to
  226. the pattern subroutines, which
  227. display c/g pics sequentially given a
  228. predetermined sequence. Again, the
  229. MSB as with the LSB we encountered
  230. earlier deals with the indirect Y
  231. function that we shall explore
  232. later.
  233.  
  234.   main1  lda #$30 ; starting pic MSB
  235.  sta temp ; store MSB in temp
  236.  jsr pattern
  237.  
  238.  lda #$30 ; starting pic MSB
  239.  sta temp ; store MSB in temp
  240.   jsr pattern0
  241.  
  242.   lda #$c0 ; this MSB is being stored
  243. but pattern1 does not use it
  244.   sta temp
  245.   jsr pattern2
  246.   jsr pattern1; fld bounce of the
  247. first intro pic only
  248.    ; located at $3000-$37e7
  249.    ; fld effect is quite annoying, so
  250. its done only once
  251.   lda #$38
  252.   sta temp
  253.   jsr p0  ; p0 routine is a part
  254. (subset) of pattern0 routine
  255.  
  256.   lda #$c0  ; the rest of these are
  257. more of the same... calls to
  258.   sta temp  ; pattern subroutines
  259.   jsr pattern2
  260.  
  261.   lda #$38
  262.   sta temp
  263.   jsr pattern0
  264.  
  265.   lda #$c0
  266.   sta temp
  267.   jsr pattern2
  268.  
  269.   lda #$30
  270.   sta temp
  271.   jsr pattern0
  272.  
  273.   lda #$c0
  274.   sta temp
  275.   jsr pattern2
  276.  
  277.   lda #$30
  278.   sta temp
  279.   jsr pattern0
  280.  
  281.   lda #$c0
  282.   sta temp
  283.   jsr pattern2
  284.  
  285.   lda #$38
  286.   sta temp
  287.   jsr p0
  288.  
  289.   lda #$c0
  290.   sta temp
  291.   jsr pattern2
  292.  
  293.   lda #$38
  294.   sta temp
  295.   jsr p0
  296.  
  297.   lda #$c0
  298.   sta temp
  299.   jsr pattern2
  300.  
  301.   jsr pattern3; last pattern before
  302. music loops back on itself
  303.  
  304.   jmp main1
  305.  
  306.   By now, music has looped...time to
  307. slow down again with the original
  308. pattern at the start of main1 routine
  309. (i.e., pattern routine that follows
  310. is called at the start of main1)
  311.  
  312.  
  313.     "pattern" is the first of the
  314. pattern subroutines.  Its
  315. responsibility is to take care of the
  316. first and second intro pics at the
  317. start of the program. It pulls the
  318. MSB from the temp memory location
  319. (the first intro pic), jsrs to the
  320. viewpic routine, and loads a "hit"
  321. value which the "pause" routine
  322. will then compare with an "looper"
  323. value.  This determines how long the
  324. first intro pic will be shown.  After
  325. which, "pattern" will change the MSB
  326. value (without affecting the MSB in
  327. temp) to point to the second intro
  328. pic, and then it repeats this process
  329. until the music tempo increases, upon
  330. which time "pattern" gives up control
  331. to another "patternX" subroutine.
  332.  
  333.     I mentioned earlier that I lost
  334. control of timing when I gave up some
  335. control to the music player code.
  336. That is to say, because I could not
  337. (at the time) incorporate the player
  338. code in here, I had no way of
  339. properly synching the pictures to the
  340. beat of the music as it played.  I
  341. corrected this deficiency in true
  342. 'newbie' fashion.  I used delay loops
  343. to form the core basis of what I
  344. could approximate as being a "beat"
  345. of music.  The "pattern" subroutines
  346. use the "pause" subroutine (which
  347. includes the core delay loops along
  348. with "hit" and "looper" comparison)
  349. in order to determine how long a C/G
  350. pic should be displayed as the music
  351. plays in the background.  I had to
  352. manually figure out how long it would
  353. take to go from its initial slow
  354. tempo to a faster tempo and then
  355. calibrate the "pattern" routine to
  356. give up control at the transition. 
  357.  
  358.  
  359.   pattern  lda temp  ; this sets up
  360. the initial -slow- flipping pattern
  361. of the
  362.  
  363.   jsr viewpic ; pics to match the -
  364. slow- tempo start to the AMJ tune
  365.   lda #$11
  366.   sta hit
  367.   jsr pause
  368.   lda #$08
  369.   jsr viewpic
  370.   lda #$11
  371.   sta hit
  372.   jsr pause
  373.   lda temp
  374.   jsr viewpic
  375.   lda #$11
  376.   sta hit
  377.   jsr pause
  378.   lda #$08
  379.   jsr viewpic
  380.   lda #$11
  381.   sta hit
  382.   jsr pause
  383.   rts
  384.  
  385.  
  386.     The other "patternX" routines and
  387. their subsets (p0, p10, etc.)
  388. basically perform addition or
  389. subtraction operations on the MSB
  390. they initially pull from the temp
  391. location.  By doing so, you can
  392. display a number of different
  393. pictures in sequence with a minimum
  394. of effort.  Recall that the pics are
  395. saved into memory initially with some
  396. organization behind it. That pre-
  397. planning combined with addition (adc)
  398. or subtraction (sbc) operations
  399. allowed me to display pictures in the
  400. order I desired. For example, assume
  401. that picture 1 is entitled "Boy",
  402. picture 2 is entitled "meets", and
  403. picture 3 is entitled "Girl".  "Boy"
  404. is at $3000, "meets" is at $3800, and
  405. "Girl" is at $4000.  The MSB
  406. represents the first 2 digits of the
  407. hex addresses I have just given, so
  408. "Boy" MSB is $30, "meets" is $38, and
  409. "Girl" is $40.  Notice that each of
  410. these MSB's is precisely #$08 hex
  411. numbers apart!  Since we haven't gone
  412. into the indirect Y function yet this
  413. may be a little premature, but it is
  414. logical to assume that if we had an
  415. indexing system in place all we would
  416. have to do in order to move from
  417. picture to picture would be to either
  418. add or subtract #$08!  So basically
  419. our pictures are 8 units apart, for
  420. simplification as follows:
  421.  
  422.   lda 30   : Our house is at 30 main
  423. street :)
  424.  
  425.  jsr viewpic  : Ask a photographer to
  426. photograph and display our house
  427.  
  428. adc  8   : Inform the photographer
  429. that the next house is 8 blocks down
  430.  
  431. jsr viewpic  : Ask the photographer
  432. to photograph and display -that-
  433. house
  434.  
  435.     In actual code, if I wanted the
  436. pictures to come out sequentially as
  437. Boy meets Girl (remember the
  438. addresses we specified above) it
  439. would be
  440.  
  441.  lda #$30   : tell viewpic that "Boy"
  442. is at $3000  (#$30 = MSB = first two
  443.   : digits of the hex number).
  444.  
  445.  jsr viewpic  : display "Boy"
  446.  
  447.  clc ; CLC - Clears the Carry Flag..
  448. required step before addition
  449.  
  450.  adc #$08   : add another #$08 to the
  451. "Boy" address..#$30 + 08 = #$38
  452.   : in other words, the address for
  453. "meets" which is $3800.
  454.  
  455.  jsr viewpic  : display "meets"
  456.  clc : required
  457.  adc #$08   : add another #$08 to the
  458. "meets" address..#$38 + 08 = #$40
  459.   : in other words, the address for
  460. "Girl" which is $4000.
  461.   : REMEMBER, we are adding in
  462. HEXADECIMAL...
  463. jsr viewpic  : display "Girl"
  464.  
  465.     Running this routine (and for
  466. now, don't worry about how viewpic
  467. works) within this program would
  468. allow us to display "Boy meets Girl".
  469. Simple, eh?  The basic concepts hold
  470. for patternX routines that use
  471. subtraction except that instead of
  472. CLC, you are required to do a SEC
  473. before a subtraction operation.
  474.  
  475.     You will notice that the patternX
  476. routines jsr to the delay loop (e.g.,
  477. loop1) routines more directly than
  478. the "pattern" routines.  This is
  479. because "pattern" required a much
  480. longer delay and this is why "hit"
  481. and "looper" were created.
  482.  
  483.   pattern0 lda temp
  484.   jsr viewpic
  485.   jsr loop1
  486.  
  487.   lda #$08 ; Load oddball MSB
  488.   jsr viewpic
  489.   jsr loop1
  490.  
  491.   p0   lda temp ; Load MSB from temp
  492.   clc
  493.   adc #$08 ; Add #$08 to it
  494.   sta temp ; Store MSB in temp
  495.   jsr viewpic
  496.   jsr loop1
  497.   lda temp ; Bring back MSB
  498.   cmp #$b8 ; Is the MSB at the
  499.   bne p0 ; final pic? $b800
  500.   rts
  501.  
  502.   pattern1 lda #$30
  503.   jsr viewpic
  504.   jsr fldmain
  505.   jsr loop2
  506.   rts
  507.  
  508. pattern2 lda #$c8 ; Load 2nd oddball
  509. MSB
  510.   jsr viewpic
  511.   jsr loop1
  512.  
  513.   p10  lda temp
  514.   sec
  515.   sbc #$08
  516.   sta temp
  517.   cmp #$30
  518.   beq p10
  519.   jsr viewpic
  520.   jsr loop1
  521.   lda temp
  522.   cmp #$28
  523.   bne p10
  524.   rts
  525.  
  526.   pattern3 lda #$c8
  527.   jsr viewpic
  528.   jsr loop1
  529.   lda #$78
  530.   jsr viewpic
  531.   jsr loop1
  532.   lda #$a0
  533.   jsr viewpic
  534.   jsr loop1
  535.   lda #$40
  536.   jsr viewpic
  537.   jsr loop1
  538.   lda #$38
  539.   jsr viewpic
  540.   jsr loop1
  541.   lda #$30
  542.   jsr viewpic
  543.   jsr loop1
  544.   lda #$08
  545.   jsr viewpic
  546.   jsr loop1
  547.   lda #$60
  548.   jsr viewpic
  549.   jsr loop1
  550.   lda #$a8
  551.   jsr viewpic
  552.   jsr loop1
  553.   lda #$68
  554.   jsr viewpic
  555.   jsr loop1
  556.   lda #$70
  557.   jsr viewpic
  558.   jsr loop1
  559.   lda #$80
  560.   jsr viewpic
  561.   jsr loop1
  562.   lda #$90
  563.   jsr viewpic
  564.   jsr loop1
  565.   lda #$88
  566.   jsr viewpic
  567.   jsr loop1
  568.   jsr loop1
  569.   jsr loop1
  570.   jsr loop1
  571.   jsr loop1
  572.   ldx #$30
  573.   jsr d1
  574.   rts
  575.  
  576.  
  577.     Ah, here we have reached the
  578. famous "viewpic".  You will notice it
  579. doesn't do much.  In fact, all it
  580. does is store the MSB pointer for the
  581. indirect Y function and "passes the
  582. buck" so to speak to the display
  583. routine.  :)
  584.  
  585.  viewpic  sta point+1; Store MSB
  586. pointer
  587.   jsr display
  588.   rts
  589.  
  590.  
  591.     WARNING : INELEGANT timing
  592. solutions up ahead...be afraid, be
  593. very afraid...
  594.  
  595.   pause  jsr loop1
  596.   inc looper
  597.   lda looper
  598.   cmp hit
  599.   bne pause
  600.   lda #$00
  601.   sta looper
  602.   rts
  603.  
  604.   loop1  ldx #$fd
  605.   jmp d1
  606.  
  607.   loop2  ldx #$01
  608.   jmp d1
  609.  
  610.   d1   ldy #$ff
  611.   d2   dey
  612.   bne d2
  613.   dex
  614.   bne d1
  615.   rts
  616.  
  617.     "loop1" encompasses "d1", and
  618. "d2".  The whole scheme is a loop
  619. within a loop, with the idea being to
  620. be able to get "loop1" to
  621. approximately equal one beat of the
  622. music playing in the background.
  623. After about 30+ (!!!) recompiles, I
  624. got it almost perfect on an NTSC
  625. machine.  The music plays 17% slower
  626. on a PAL (european, australian)
  627. machine and so this demo is
  628. horribly out of synch in PAL.  For
  629. those of you who are wondering, Mr.
  630. George Taylor calculated the delay
  631. loops to be about 2.8% slower on a
  632. PAL machine when taking into
  633. consideration the slower PAL CPU and
  634. the penalties incurred due to "bad
  635. lines" (when the vic chip steals cpu
  636. cycles on the bus).  As mentioned
  637. earlier, the "pause" routine
  638. encompasses everything "loop1" has to
  639. offer and extends the delay even
  640. further.  The "loop2" routine would
  641. seem to be useless but it is called
  642. by the fld-bounce routines.  The fld
  643. takes longer than a regular display
  644. so I figured I would only need to
  645. call a delay routine that was a
  646. fraction of a music "beat" (which is
  647. what "loop1" tries to be).
  648.  
  649.     Now we get to the real nitty
  650. gritty of the whole thing.  The
  651. "display" routine and its subsets.
  652. These make use of the indirect Y
  653. function which Mensch and company
  654. thankfully chose to implement in the
  655. 6502.
  656.  
  657.     But wait, we haven't really gone
  658. into the indirect Y, have we?  Nope,
  659. because it is tricky to explain.
  660. Like with movies or sports events,
  661. you have to be there in order to get
  662. the feel for it.  In general, it is
  663. an index system that uses a zero page
  664. pointer of your choice in order to
  665. jump around to this or that memory
  666. location.  But that's too
  667. vague...let's really explore it.
  668.  
  669.     Do you recall that at the start
  670. of the code we defined a few labels
  671. and basically equated them as memory
  672. locations? We said that "point = $fb"
  673. among other things. That is our
  674. memory (zp) pointer for the Least
  675. Significant Byte (LSB) and in the
  676. "display" routine below you will see
  677. a reference to point+1 which is our
  678. memory (zero-page) pointer for the
  679. Most Significant Byte (MSB).
  680.  
  681.     An address in memory is made up
  682. of two bytes, namely the MSB and
  683. LSB.
  684. Think of the MSB as the first two
  685. digits and the LSB as the last two
  686. digits, as follows:
  687.  
  688.   $c000 = $c0 MSB + 00 LSB
  689.  
  690.   $00c0 = $00 MSB + c0 LSB
  691.  
  692.     The two together make up a 16-bit
  693. address and due to how the 6502
  694. works, it is one reason why 64
  695. kilobytes can be accessed directly
  696. (2^16 = 65536).
  697.  
  698.     The indirect Y function allows
  699. you to set up an MSB and LSB pointer
  700. in zero page (ie., the first 256
  701. bytes of memory from $0000 to $00ff).
  702.  
  703.     Note : You can't set a pointer in
  704. locations $0000, $0001, and $00ff.
  705. The LSB pointer I chose was $fb and
  706. by definition, the MSB pointer is
  707. automatically one memory location
  708. higher than the LSB pointer, so my
  709. MSB pointer is at $fc (point + 1).
  710.  
  711.     The "display" routines make use
  712. of the pointer functions as an index
  713. to copy C/G picture data to screen
  714. and color memory.  But how does it do
  715. it, right?
  716.  
  717.    The "viewpic" routine we
  718. encountered earlier sets the MSB to
  719. the MSB of the picture that is about
  720. to be displayed.  So for the first
  721. intro pic at $3000 this would be an
  722. MSB of #$30.  Our LSB was set to zero
  723. (#$00) at the start of the program.
  724. So we have an MSB of #$30 and an LSB
  725. of #$00 = $3000 address. "display"
  726. now sets the Y register to zero (ldy
  727. #$00), "pa1" is now ready to copy
  728. memory.
  729.  
  730.     NOTE : For all the examples
  731. shown, we will use the MSB of the
  732. first intro pic
  733.  
  734.    ($3000 = $30 MSB = first two
  735. digits).  The rest of the program
  736. changes the MSB on the fly so that
  737. when the "display" routine is
  738. reached, new pics can be displayed.
  739. If the MSB didn't change beyond the
  740. simple incrementations you will see
  741. below, we'd be stuck with displaying
  742. one pic.
  743.  
  744.   display  ldy #$00  ; "display"
  745. encompasses all the memory moves that
  746. follow
  747.  
  748.  ;--------screen data moves----------
  749.  
  750.  
  751.   pa1  lda (point),y ; $x000  $x800
  752.   sta $0400,y
  753.   iny
  754.   bne pa1
  755.  
  756.     As you can see "pa1" takes the
  757. LSB of the pointer and uses the Y
  758. register to increment it (with INY)
  759. and then uses the same increment to
  760. store values to screen memory (which
  761. starts at $0400).  In long form, this
  762. routine is just doing this :
  763.  
  764.  LDA $3000  ; take the first byte
  765. from the stored pic in memory
  766.  
  767.  STA $0400  ; put the first byte to
  768. the first screen memory location
  769.  
  770.  LDA $3001  ; take the second byte
  771. from the stored pic in memory
  772.  
  773.  STA $0401  ; put the second byte to
  774. the second screen memory location
  775.  
  776.  LDA $3002  ; take the third byte
  777. from the stored pic in memory
  778.  
  779.  STA $0402  ; put the third byte to
  780. the third screen memory location
  781.  
  782. The INY instruction can only
  783. increment 256 times before the LSB
  784. runs out and it starts looping back
  785. to zero, so what we do now is
  786. increment the MSB ! (Remember, the
  787. BNE instruction checks when Y is
  788. equal to zero and moves on
  789. to the next routine -- Also, remember
  790. that Y itself does not change the
  791. LSB pointer, it only adds to the LSB
  792. *value* during the loop.  LSB pointer
  793. itself stays the same, which means we
  794. can use it in the next routine
  795. without resetting it - the one we do
  796. increment is the MSB - via the INC
  797. instruction).
  798.  
  799.   ldy #$00
  800.   inc point+1
  801.  
  802.     The previous routine "pa1" filled
  803. the first 256 bytes of screen memory
  804. with the first 256 bytes of our
  805. stored pic (i.e., it copied memory
  806. locations from $3000-$30ff to $0400-
  807. $04ff).  We have just increased our
  808. MSB by one (using the INC point+1 -
  809. remember point+1 = our MSB in zero
  810. page).  "pa2" will now do the same
  811. thing as "pa1" except it is now
  812. working on the next 256 bytes (i.e.,
  813. it will copy memory locations from
  814. $3100-$31ff to $0500-$05ff).
  815.  
  816.   pa2  lda (point),y ; $x100  $x900
  817.   sta $0500,y
  818.   iny
  819.   bne pa2
  820.  
  821.   ldy #$00
  822.   inc point+1
  823.  
  824.     The MSB pointer is incremented
  825. again...  $3200-$32ff to $0600-06ff.
  826. Please remember we are using the MSB
  827. of the first pic in this example.
  828.  
  829.   pa3  lda (point),y ; $x200  $xa00
  830.   sta $0600,y
  831.   iny
  832.   bne pa3
  833.  
  834.   ldy #$00
  835.   inc point+1
  836.  
  837.     The MSB pointer is incremented
  838. again...  $3300-$33ff to $0700-$07ff
  839. ($07e7) Please remember we are using
  840. the MSB of the first pic in this
  841. example.
  842.  
  843.   pa4  lda (point),y ; $x300  $xb00
  844.   sta $0700,y
  845.   iny
  846.   bne pa4
  847.  
  848.  ;--------color data moves---------
  849.  
  850.   ldy #$00
  851.   inc point+1
  852.  
  853.     Are we seeing a pattern here?  :)
  854. The MSB keeps getting incremented so
  855. as to allow yet another 256 byte
  856. copy-fill to occur.  But now things
  857. change a little since we will now
  858. copy color memory.  Not a problem
  859. because when we first organized our
  860. pictures in memory we put color data
  861. "RIGHT BEHIND" the screen data!!
  862. Recall, screen data takes up the
  863. first 1 KB while color data takes up
  864. the last KB  (2 KB total per pic).
  865. So what do we do?  We keep
  866. incrementing the MSB until the end of
  867. the pic is reached, but now we
  868. redirect our copy to the VIC color
  869. memory area ($d800-$dbff).
  870.  
  871.     "cpa1" copies $3400-$34ff to
  872. $d800-$d8ff.  Please remember we are
  873. using the MSB of the first pic in
  874. this example.
  875.  
  876.   cpa1     lda (point),y ; $x400
  877. $xc00 ; we are now in the second
  878. kilobyte
  879.  
  880.   sta $d800,y   ; of our stored pic
  881. data in memory.. in other words
  882.  
  883.   iny    ; this continual MSB
  884. incrementation has gone through
  885.  
  886.   bne cpa1  ; the first KB and has
  887. now hit the second KB where color
  888. memory for the pictures resides
  889.  
  890.   ldy #$00
  891.   inc point+1 ; increment that MSB
  892. yet again..
  893.  
  894.   cpa2   lda (point),y ; $x500
  895. $xd00
  896.   sta $d900,y ; copies $3500-35ff to
  897. $d900-$d9ff
  898.   iny
  899.   bne cpa2
  900.  
  901.   ldy #$00
  902.   inc point+1 ; increment that MSB
  903. yet again..
  904.  
  905.   cpa3   lda (point),y ; $x600
  906. $xe00
  907.   sta $da00,y ; copies $3600-36ff to
  908. $da00-$daff
  909.   iny
  910.   bne cpa3
  911.  
  912.   ldy #$00
  913.   inc point+1 ; increment that MSB
  914. for the last time!
  915.  
  916.   cpa4   lda (point),y ; $x700
  917. $xf00
  918.   sta $db00,y ; copies $3700-$37ff to
  919. $db00-$dbff ($dbe7)
  920.   iny
  921.   bne cpa4
  922.   rts  ; return back to original
  923. calling routine, whatever
  924.    ; that may be!
  925.  
  926. ;----------------------------------
  927.  
  928.   nullpic  ldy #$00 ; this is
  929. useless, i never did anything with
  930. nullpic.  I wanted to expand this to
  931. build some kind of random pic or
  932. blank screen.. but i forgot about
  933. it..
  934.  
  935. ;------fld routine------------------
  936.  
  937.     FLD is known as Flexible Line
  938. Distancing and the routine that
  939. follows is an amalgam of something
  940. The Phantom/FOE did in a Coder's
  941. World 3 article. I will refer the
  942. reader to that article and a more
  943. comprehensive analysis of FLD in C=
  944. Hacking Issue #7.  In brief summary,
  945. FLD is basically a raster trick that
  946. bounces the whole screen up and down
  947. quickly without having to engage in
  948. moving screen memory or vertically
  949. scrolling the actual picture data.
  950. This illustrates a good point about
  951. coding on the C-64.  The best
  952. "coders" may not necessarily be the
  953. ones who best know the 6510 CPU.
  954. Generally, at least in the 'demo
  955. world', talent is assessed on how
  956. well the individual knows how to
  957. properly abuse the ancillary chips
  958. VIC, SID, CIA, etc.
  959.  
  960.     The FLD technique from my
  961. standpoint was an exercise in trial
  962. and error.  I sadly did not use a
  963. sine table to coordinate the bounce-
  964. effect.  I basically sat there
  965. tweaking it left and right until it
  966. did what I wanted it to do on my NTSC
  967. machine.  In other words, once I got
  968. it to bounce the first intro
  969. pic a few times and gracefully
  970. depart, I was content.  On PAL
  971. machines the effect is quite skewed
  972. and is not recommended for young
  973. viewers in the audience as it is
  974. rather grotesque :).
  975.  
  976.    fldmain  lda #$00
  977.    sta temp2
  978.  
  979.    fld  lda #$2a
  980.    cmp $d012
  981.    bne fld
  982.    lda temp2
  983.    cmp #$4f
  984.    beq fldmain2
  985.  
  986.   start  ldx temp2
  987.   bounce ldy $d012
  988.   cpy $d012
  989.   dey
  990.   tya
  991.   and #$07
  992.   ora #$10
  993.   sei
  994.   sta $d011
  995.   cli
  996.   dex
  997.   bne bounce
  998.   ldy #$15
  999.   sty $d018
  1000.   lda temp2
  1001.   clc
  1002.   adc #$07
  1003.   sta temp2
  1004.   jmp fld
  1005.  
  1006.   fldmain2 lda #$1b  ; recovers first
  1007. scn
  1008.   sta $d011 ; row from fld trick
  1009.   clc
  1010.   rts
  1011.  
  1012.  
  1013.     This is it!  The end of this
  1014. article and the end of what I hope
  1015. was an enjoyable experience for you.
  1016. Part of the disC=overy project is to
  1017. stave off entropy for as long as
  1018. possible.  The best way to do this is
  1019. to convert more order out of chaos in
  1020. our local domain - the world of 64
  1021. :).  In effect, by increasing the
  1022. interest and drive we put into these
  1023. old tanks, we shift entropy and chaos
  1024. to the rest of the computer world.
  1025. Because the universe is a closed
  1026. system, this is the best we can do
  1027. and is perhaps a lost cause
  1028. ultimately, but I'll wager no one
  1029. thought we would get this far.
  1030.  
  1031.   XmikeX
  1032.  
  1033.